package org.glutenberg.util;

import java.util.Enumeration;

import org.glutenberg.util.binarytree.ConflictResolver;
import org.glutenberg.util.binarytree.SymmetricTraversal;
import org.glutenberg.util.binarytree.Tree;

public class TreeMap {
	
	private Tree tree;
	private static TreeMapConflictResolver conflictResolver;
	
	static {
		conflictResolver = new TreeMapConflictResolver();	
	}
	static class Entry implements Map.Entry {

		private Comparable key;
		private Object value;
		
		public Entry(Comparable key, Object value){
			this.key = key;
			this.value = value;
		}
		
		public int compareTo(Object o) {
			Entry e = (Entry) o;
			return this.key.compareTo(e.key);
		}	
		
		public Object getValue() {
			return value;
		}

		public void setValue(Object value) {
			this.value = value;
		}

		public Comparable getKey() {
			return key;
		}

		public void setKey(Comparable key) {
			this.key = key;
		}
	}
	
	static class TreeMapConflictResolver extends ConflictResolver {

		public void resolveConflict(Object o1, Object o2) {
			Entry e1 = (Entry) o1;
			Entry e2 = (Entry) o2;
			e1.value = e2.value;
		}
		
	}
	
	public TreeMap(){
		this(null);
	}
	
	public TreeMap(Comparator comparator){
		this.tree = new Tree(conflictResolver, comparator, false);
	}
	
	public int size(){
		return this.tree.size();
	}
	
	public void put(Comparable key, Object value){
		this.tree.insert(new Entry(key, value));
	}
	
	public Object get(Comparable key){
		Entry keyEntry = new Entry(key, null);
		Entry entry = (Entry) this.tree.searchFirst(keyEntry);
		if(entry!=null) return entry.getValue();
		return null;
	}
	
	public boolean containsKey(Comparable key){
		Entry keyEntry = new Entry(key, null);
		Entry entry = (Entry) this.tree.searchFirst(keyEntry);
		return entry!=null;
	}
	
	public Enumeration elements(){
		return new SymmetricTraversal(this.tree);
	}
}
